import vw_users from "../database/models/vw_users.js";
import vw_mp_users from "../database/models/vw_mp_users.js";

import bcrypt from "bcrypt";
import Auth_Jwt from "../middlewares/auth/Auth_Jwt";
import WxCfg from "../config/wxcfg";
import request from "request";

var that; // 改变this指向全局
class CTRL_User {
  constructor() {
    that = this;
  }
  async Find_User_By_Email(req, res) {
    try {
      let { email } = req.body;
      const Account_Info = await vw_users.findOne({
        where: {
          email,
        },
      });
      return Account_Info;
    } catch (e) {
      return res.send({
        code: 600,
        msg: "通过EMAIL查找用户失败，检查数据",
      });
    }
  }
  async Create_User(req, res, next) {
    try {
      let { username, email, password } = req.body;

      const User_Info = await vw_users.create({
        username,
        email,
        password: bcrypt.hashSync(password, 5),
      });
      delete req.sessionStore.verify;
      return res.send({
        User_Info,
        msg: "注册成功",
        code: 200,
      });
    } catch (e) {
      res.send({
        code: 603,
        msg: "创建用户失败",
      });
    }

    next();
  }
  async Reset_Password(req, res, next) {
    try {
      let { email, password } = req.body; //前端发送来的验证邮箱

      let newpsw = {
        password: bcrypt.hashSync(password, 5), // 加密
      };

      const User_Info = await vw_users.update(newpsw, {
        where: {
          email,
        },
      });
      delete req.sessionStore.verify;
      return res.send({
        msg: "密码重置成功",
        code: 200,
      });
    } catch (e) {
      return res.send({
        msg: "重置密码失败，检查数据",
        code: 452,
      });
    }

    next();
  }

  async Login(req, res, next) {
    try {
      // that 改变this指向
      const User_Data = await that.Find_User_By_Email(req, res);
      let User_Info = User_Data.dataValues;
      let { password, uid, email } = User_Info;

      const check_password = bcrypt.compareSync(req.body.password, password);

      if (!check_password) {
        return res.send({
          msg: "密码错误",
          code: 601,
        });
      }

      const Jwt_User_Info = {
        email,
        password,
        uid,
      };

      let jwt = new Auth_Jwt(Jwt_User_Info); // 调用jwt方法
      let Token = jwt.Create_Token(); //生成jwt
      return res.send({
        msg: "登录成功",
        code: 200,
        Token,
        User_Info,
      });
    } catch (e) {
      return res.send({
        msg: "校验密码失败，检查数据",
        code: 604,
      });
    }
  }

  async Token_Login(req, res, next) {
    try {
      let token = req.headers.authorization;
      let jwt = new Auth_Jwt(token); // 调用jwt方法
      let isLogin = jwt.Verify_Token(); //校验jwt

      if (isLogin.msg == "Been_Login") {
        let { email } = isLogin.data;
        const User_Info = await vw_users.findOne({
          where: {
            email,
          },
        });
        if (User_Info == null) {
          return res.status(401).send({
            msg: isLogin.msg,
          });
        } else {
          return res.send({
            msg: "自动登录成功",
            code: 200,
            User_Info,
          });
        }
      }
    } catch (error) {
      return res.send({
        msg: "自动登录失败，检查数据",
        code: 605,
      });
      next(error);
    }
  }

  // 发起请求查询WX相关参数如openid
  async MP_Request4WxConfig(req, res, next) {
    try {
      const { code } = req.body,
        // query请求格式
        queryStr = `appid=${WxCfg.appId}&secret=${WxCfg.appSecret}&js_code=${code}&grant_type=authorization_code`,
        // wx请求LOgin 的api
        wxApi = `https://api.weixin.qq.com/sns/jscode2session?${queryStr}`,
        Promise_request = new Promise(function (resolve, reject) {
          request(wxApi, (err, response, body) => {
            // 若错误抛出错误

            if (err) return reject(err);
            // 格式化返回值
            const data = JSON.parse(body),
              { openid } = data;
            // 返回session_key,openid
            resolve(data);
          });
        });
      //  req入参 + 发起请求
      req.body.wx_res_data = await Promise_request;
      next();
    } catch (error) {
      next(error);
    }
  }

  /*
  MP-登录
    1.查询openid关联的账号
    1.1、若有直接分配token登录
    1.2、若无新建账号登录即注册
    */
  async MP_Login(req, res, next) {
    try {
      const { openid, session_key } = req.body.wx_res_data,
        User_Info = await vw_mp_users.findOne({
          where: {
            openid,
          },
        });
      // 有查到数据-直接登录
      if (User_Info) {
        const Jwt_User_Info = User_Info.dataValues,
          jwt = new Auth_Jwt(Jwt_User_Info), // 调用自封的jwt方法
          Token = jwt.Create_Token(); //生成jwt

        return res.send({
          msg: "登录成功",
          code: 200,
          Token,
          User_Info,
        });
      } else {
        // 没登陆过直接注册
        let { nickName, gender, city, province, avatarUrl, wx_res_data } =
          req.body;

        const User_Info = await vw_mp_users.create({
          nickName,
          gender,
          city,
          province,
          avatarUrl,
          openid: wx_res_data.openid,
        });
        return res.send({
          User_Info,
          msg: "注册成功",
          code: 200,
        });
      }
    } catch (error) {
      console.log(error);
      next(error);
    }
  }

  // 小程序自动登录
  async MP_Token_Login(req, res, next) {
    try {
      let token = req.headers.authorization;
      let jwt = new Auth_Jwt(token); // 调用jwt方法
      let isLogin = jwt.Verify_Token(); //校验jwt

      if (isLogin.msg == "Been_Login") {
        let { mp_uid } = isLogin.data,
        User_Info = await vw_mp_users.findOne({
          where: {
            mp_uid,
          }
        });
        if (User_Info == null) {
          return res.status(401).send({
            msg: isLogin.msg,
          });
        } else {
          return res.send({
            msg: "自动登录成功",
            code: 200,
            User_Info,
          });
        }
      }
    } catch (error) {
      return res.send({
        msg: "自动登录失败，检查数据",
        code: 605,
      });
    }
  }
}

export default new CTRL_User();
